home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Graphics 2D / BrightContrastEngine / BCDemo.c next >
Encoding:
Text File  |  2000-09-28  |  27.8 KB  |  848 lines  |  [TEXT/CWIE]

  1. //****************************************************************************************
  2. // Brightness/Contrast Demo
  3. //
  4. // Written by Jack Fu, 09/1999
  5. // Copyright 1999 by Apple Computer, Inc.
  6. //----------------------------------------------------------------------------------------
  7.  
  8. //----------------------------------------------------------------------------------------
  9. // Includes
  10. //----------------------------------------------------------------------------------------
  11. #include <AVComponents.h>
  12.  
  13. #include "BCEngine.h"
  14.  
  15.  
  16. //----------------------------------------------------------------------------------------
  17. // Includes
  18. //----------------------------------------------------------------------------------------
  19. #define    SUPPORT_OLD_BC_ENGINES    1
  20.  
  21.  
  22. //----------------------------------------------------------------------------------------
  23. // Private Defines
  24. //----------------------------------------------------------------------------------------
  25. #define kSleepTime            10        // in ticks
  26.  
  27. #define kMBARResID            128
  28. #define kAppleMenuResID        128
  29. #define kFileMenuResID        129
  30. #define kEditMenuResID        130
  31.  
  32. enum    // menu items for MENU kFileMenuResID
  33. {
  34.     kQuitMenuItem = 1
  35. };
  36.  
  37. enum    // menu items for MENU kEditMenuResID
  38. {
  39.     kUndoMenuItem = 1
  40. };
  41.  
  42. #define kDialogID                128
  43. #define kComponentAlertID        129
  44. #define kComponentOpenAlertID    130
  45. #define kComponentTargetAlertID    131
  46. #define kComponentMiscAlertID    132
  47. #define kDMAlertID                133
  48.  
  49. enum    // dialog items for DITL (ID = kDialogID )
  50. {
  51.     kContrastTextItem = 1,
  52.     kContrastSliderItem,
  53.     kBrightnessTextItem,
  54.     kBrightnessSliderItem,
  55.     kContrast0PctTextItem,
  56.     kContrast100PctTextItem,
  57.     kBrightness0PctTextItem,
  58.     kBrightness100PctTextItem
  59. };
  60.  
  61.  
  62. //----------------------------------------------------------------------------------------
  63. // Private Prototypes
  64. //----------------------------------------------------------------------------------------
  65. typedef struct OurDMNotifyData 
  66. {
  67.     ComponentInstance    engine;
  68.     DialogPtr            dp;
  69.     ControlHandle        brightnessCtl;
  70.     ControlHandle        contrastCtl;
  71. } OurDMNotifyData, *OurDMNotifyDataPtr, **OurDMNotifyDataHdl;
  72.  
  73.  
  74. //----------------------------------------------------------------------------------------
  75. // Private Prototypes
  76. //----------------------------------------------------------------------------------------
  77. OSErr         InitializeApp                (void);
  78. void         CleanUpApp                    (OurDMNotifyDataPtr dataP);
  79.  
  80. DialogPtr     SetupDialog                    (ComponentInstance engine, OurDMNotifyDataPtr dataP);
  81. OSErr         RunEventLoop                (DialogPtr dp, ComponentInstance engine);
  82. OSErr         HandleMouseDown                (EventRecord* theEvent, DialogPtr dp, ComponentInstance engine, Boolean *handled);
  83. OSErr         HandleMenuSelect            (EventRecord* theEvent, ComponentInstance engine, Boolean *handled);
  84.  
  85. OSErr         OpenEngine                    (ComponentInstance *engine);
  86. OSErr         FindBCEngine                (AVIDType displayID, Component *theEnginePtr);
  87. OSErr         ResetSettings                (ComponentInstance engine, short brightness, short contrast);
  88. OSErr         UpdateSliders                (OurDMNotifyDataPtr dataP);
  89. static pascal void BCTargetIterator        (void* userData, DMListIndexType itemIndex, DMComponentListEntryPtr listInfo);
  90.  
  91. pascal OSErr AEOpenHandler                (AppleEvent *messagein, AppleEvent *reply, long refln);
  92. pascal OSErr AEQuitHandler                (AppleEvent *messagein, AppleEvent *reply, long refIn);
  93.  
  94. pascal void ContrastActionProc            (ControlHandle theControl, short partCode);
  95. pascal void BrightnessActionProc        (ControlHandle theControl, short partCode);
  96. pascal void BrightnessContrastNotify    (void* userData, short theMessage, void* notifyData);
  97.  
  98.  
  99. //----------------------------------------------------------------------------------------
  100. // Globals
  101. //----------------------------------------------------------------------------------------
  102. Boolean                        gTimeToQuit             = false;
  103. ControlActionUPP            gBrightnessSliderUPP     = NULL;        
  104. ControlActionUPP            gContrastSliderUPP         = NULL;        
  105. DMExtendedNotificationUPP    gDMNotifyUPP            = NULL;
  106. DisplayIDType                gOurDisplayID;
  107. short                        gInitialBrightness;
  108. short                        gInitialContrast;
  109.  
  110.  
  111. //****************************************************************************************
  112. // main
  113. //
  114. //----------------------------------------------------------------------------------------
  115. int main (void)
  116. {
  117.     OSErr                result         = noErr;
  118.     DialogPtr            myDialog     = NULL;
  119.     ComponentInstance    engine;
  120.     OurDMNotifyData        data;
  121.         
  122.     result = InitializeApp();
  123.     
  124.     //--- First, we must be able to find a brightness/contrast engine ---
  125.     if ( result == noErr )
  126.         result = OpenEngine( &engine );
  127.     
  128.     //--- Store the initial engine settings in case we want to undo later ---
  129.     if ( result == noErr )
  130.     {
  131.         result = ContrastEngineGetBrightness( engine, &gInitialBrightness );
  132.         if ( result == noErr )
  133.             result = ContrastEngineGetContrast( engine, &gInitialContrast );
  134.     }
  135.     
  136.     if ( result == noErr )
  137.     {
  138.         //--- Bring up our dialog window ----------------------------------
  139.         myDialog = SetupDialog( engine, &data );
  140.             
  141.         //--- Do the main loop -------------------------------------------
  142.         if ( myDialog != NULL )
  143.             result = RunEventLoop( myDialog, engine );
  144.     }
  145.     
  146.     CleanUpApp( &data );
  147.     
  148.     return result;    
  149. }
  150.  
  151. //****************************************************************************************
  152. // InitializeApp
  153. //
  154. //----------------------------------------------------------------------------------------
  155. OSErr InitializeApp (void)
  156. {
  157.     OSErr        result             = noErr;
  158.     Handle        myMenu             = NULL;
  159.     MenuHandle    appleMenuHandle = NULL;    
  160.         
  161.     //--- Initialize all needed managers ---------------------------------
  162.     InitGraf(&qd.thePort);
  163.     InitFonts();
  164.     InitWindows();
  165.     InitMenus();
  166.     TEInit();
  167.     InitDialogs(nil);
  168.     InitCursor();
  169.  
  170.     //--- Required Suite -------------------------------------------------
  171.     result = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(AEOpenHandler), 0L, false );
  172.     if ( result == noErr )
  173.         result = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(AEOpenHandler), 0L, false );
  174.     if ( result == noErr )
  175.         result = AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerProc(AEOpenHandler), 0L, false );
  176.     if ( result == noErr )
  177.         result = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(AEQuitHandler), 0L, false );
  178.         
  179.     //--- Initialize the Menu Bar ----------------------------------------
  180.     if ( result == noErr )
  181.     {
  182.         myMenu = GetNewMBar( kMBARResID );
  183.         SetMenuBar( myMenu );
  184.         appleMenuHandle = GetMenuHandle( kAppleMenuResID );
  185.         AppendResMenu( appleMenuHandle, 'DRVR' );    
  186.         
  187.         //--- When all is said and done, draw the menu ------------
  188.         DrawMenuBar();
  189.     }
  190.     
  191.     return result;
  192. }
  193.  
  194. //****************************************************************************************
  195. // CleanUpApp
  196. //
  197. //----------------------------------------------------------------------------------------
  198. void CleanUpApp (OurDMNotifyDataPtr dataP)
  199. {
  200.     ProcessSerialNumber    currentPSN;
  201.  
  202.     //--- Remove Display Manager's notification proc -------------
  203.     GetCurrentProcess( ¤tPSN );
  204.     DMRemoveExtendedNotifyProc( gDMNotifyUPP, (void*) dataP, ¤tPSN, (unsigned short) NULL);
  205.     DisposeRoutineDescriptor( gDMNotifyUPP );
  206.     
  207.     //--- Dispose the other routine descriptors ------------------
  208.     DisposeRoutineDescriptor( gBrightnessSliderUPP );
  209.     DisposeRoutineDescriptor( gContrastSliderUPP );
  210.     
  211.     return;
  212. }
  213.  
  214. //****************************************************************************************
  215. // AEOpenHandler
  216. //
  217. //  - used to handle opendoc, openapp, and printdoc AE events
  218. //----------------------------------------------------------------------------------------
  219. pascal OSErr AEOpenHandler (AppleEvent *messagein, AppleEvent *reply, long refIn)
  220. {
  221. #pragma unused (messagein, refIn, reply)
  222.             
  223.     return noErr;
  224. }
  225.  
  226. //****************************************************************************************
  227. // AEQuitHandler
  228. //
  229. //    
  230. //----------------------------------------------------------------------------------------
  231. pascal OSErr AEQuitHandler (AppleEvent *messagein, AppleEvent *reply, long refIn)
  232. {
  233. #pragma unused (messagein, refIn, reply)
  234.     
  235.     gTimeToQuit = true;
  236.     return noErr;
  237. }
  238.  
  239.  
  240. //****************************************************************************************
  241. #pragma mark -
  242. #pragma mark • Event Handling Routines
  243. #pragma mark -
  244. //****************************************************************************************
  245.  
  246. //****************************************************************************************
  247. // RunEventLoop
  248. //
  249. //    
  250. //----------------------------------------------------------------------------------------
  251. OSErr RunEventLoop (DialogPtr dp, ComponentInstance engine)
  252. {
  253.     OSErr            err         = noErr;
  254.     Boolean            handled     = false;
  255.     EventRecord        theEvent;
  256.     short            itemHit;
  257.     
  258.     while ( err == noErr && !gTimeToQuit )
  259.     {
  260.         if ( WaitNextEvent(everyEvent, &theEvent, kSleepTime, NULL) )
  261.         {
  262.             //--- Handle events ------------------------------------
  263.             switch (theEvent.what)
  264.             {
  265.                 case updateEvt:            
  266.                 case activateEvt:                
  267.                 case mouseDown:            
  268.                     if ( IsDialogEvent(&theEvent) )
  269.                         DialogSelect(&theEvent, &dp, &itemHit);
  270.                     else
  271.                         err = HandleMouseDown( &theEvent, dp, engine, &handled );
  272.                     break;
  273.             
  274.                 case keyDown:
  275.                 case autoKey:
  276.                     //--- We only care about Command-key shortcuts -----
  277.                     if ( theEvent.modifiers & cmdKey )
  278.                         err = HandleMenuSelect( &theEvent, engine, &handled );
  279.                     break;
  280.                                     
  281.                 case kHighLevelEvent:
  282.                     err = AEProcessAppleEvent( &theEvent );
  283.                     handled = true;
  284.                     break;
  285.                     
  286.                 case diskEvt:
  287.                 case osEvt:                    
  288.                 default:
  289.                     break;
  290.             }
  291.         }
  292.     }
  293.         
  294.     return err;
  295. }
  296.  
  297. //****************************************************************************************
  298. // HandleMouseDown
  299. //
  300. //----------------------------------------------------------------------------------------
  301. OSErr HandleMouseDown (EventRecord* theEvent, DialogPtr dp, ComponentInstance engine, Boolean *handled)
  302. {
  303.     OSErr            result         = noErr;
  304.     Boolean            wasActive     = true;
  305.     WindowPtr        theWindow;
  306.     short            partCode;
  307.     
  308.     //--- Figure out which window was hit -------------------------
  309.     partCode = FindWindow( theEvent->where, &theWindow );
  310.  
  311.     //--- Figure out where the window was hit ---------------------    
  312.     switch( partCode )
  313.     {
  314.         case inMenuBar:
  315.             result = HandleMenuSelect( theEvent, engine, handled );
  316.             break;
  317.             
  318.         case inSysWindow:
  319.             SystemClick( theEvent, theWindow );
  320.             *handled = true;
  321.             break;
  322.             
  323.         case inDrag:
  324.             {
  325.                 //--- Allow the user to drag our window around --------
  326.                 RgnHandle screenbounds = GetGrayRgn();
  327.                 DragWindow( (WindowPtr)dp, theEvent->where, &(*screenbounds)->rgnBBox );
  328.             }
  329.             break;
  330.                     
  331.         case inDesk:
  332.         case inGrow:
  333.         case inContent:
  334.         case inGoAway:
  335.         case inZoomIn:
  336.         case inZoomOut:
  337.             break;
  338.             
  339.     }
  340.  
  341.     return result;
  342. }
  343.  
  344. //****************************************************************************************
  345. // HandleMenuSelect
  346. //
  347. //----------------------------------------------------------------------------------------
  348. OSErr HandleMenuSelect (EventRecord* theEvent, ComponentInstance engine, Boolean *handled)
  349. {
  350.     OSErr    result = noErr;
  351.     long    menuVal;
  352.     
  353.     //--- Translate event to something useful -------------------
  354.     if ( theEvent->modifiers & cmdKey )
  355.         menuVal = MenuKey( theEvent->message & charCodeMask );
  356.     else
  357.         menuVal = MenuSelect( theEvent->where );
  358.     
  359.     if ( HiWord( menuVal ) == kFileMenuResID && LoWord( menuVal ) == kQuitMenuItem )
  360.     {
  361.         //--- The user has hit Command-Q -----------------------
  362.         gTimeToQuit = true;
  363.         *handled = true;
  364.     }
  365.     else if ( HiWord( menuVal ) == kEditMenuResID && LoWord( menuVal ) == kUndoMenuItem )
  366.     {
  367.         //--- The user has hit Command-Z to undo: reset the contrast/brightness 
  368.         //--- settings to what we started with
  369.         result = ResetSettings( engine, gInitialBrightness, gInitialContrast );
  370.     }
  371.  
  372.     //--- Un-hilite the menu bar --------------------------------
  373.     HiliteMenu( 0 );
  374.         
  375.     return result;
  376. }
  377.  
  378. //****************************************************************************************
  379. // UpdateSliders
  380. //
  381. //    
  382. //----------------------------------------------------------------------------------------
  383. OSErr UpdateSliders (OurDMNotifyDataPtr dataP)
  384. {
  385.     OSErr    result = noErr;
  386.     short    value;
  387.  
  388.     //--- Get the current brightness and set the brightness slider control ----
  389.     result = ContrastEngineGetBrightness( dataP->engine, &value );
  390.     if ( result == noErr )
  391.     {
  392.         SetControlValue( dataP->brightnessCtl, value );
  393.         
  394.         //--- Get the current contrast and set the contrast slider control -----
  395.         result = ContrastEngineGetContrast( dataP->engine, &value );
  396.         if ( result == noErr )
  397.             SetControlValue( dataP->contrastCtl, value );     
  398.     }
  399.             
  400.     return result;
  401. }
  402.  
  403.  
  404. //****************************************************************************************
  405. #pragma mark -
  406. #pragma mark • Engine Routines
  407. #pragma mark -
  408. //****************************************************************************************
  409.  
  410. //****************************************************************************************
  411. // OpenEngine
  412. //
  413. //    
  414. //----------------------------------------------------------------------------------------
  415. OSErr OpenEngine (ComponentInstance *engine)
  416. {
  417.     OSErr            result         = noErr;
  418.     GDHandle        aGDevice     = NULL;
  419.     DisplayIDType    displayID     = kInvalidDisplayID;
  420.     Component        bcEngine;
  421.     
  422.     //--- In the demo, we only mess with the main GDevice. In general, one could
  423.     //--- use a combination of DMGetFirstScreenDevice and DMGetNextScreenDevice
  424.     //--- (see Displays.h) to go through the exhaustive list of displays.
  425.     aGDevice = GetMainDevice();
  426.     if ( aGDevice != NULL )
  427.     {
  428.         //--- Get the DisplayID for this GDevice --------------------
  429.         result = DMGetDisplayIDByGDevice( aGDevice, &displayID, false );
  430.     }
  431.     
  432.     //--- Check for Display Manager errors
  433.     if ( aGDevice == NULL || result != noErr )
  434.     {
  435.         StopAlert( kDMAlertID, NULL );
  436.         return -1;
  437.     }    
  438.  
  439.     //--- Find an engine for this DisplayID -------------------------------
  440.     gOurDisplayID = displayID;
  441.     result = FindBCEngine( displayID, &bcEngine );
  442.     if ( result != noErr )
  443.     {
  444.         StopAlert( kComponentAlertID, NULL );
  445.         return -2;
  446.     }
  447.     
  448.     //--- Open the engine --------------------------------------------------
  449.     *engine = OpenComponent( bcEngine );
  450.     if ( *engine == NULL )
  451.     {
  452.         StopAlert( kComponentOpenAlertID, NULL );
  453.         return -3;
  454.     }
  455.     
  456.     //--- Tell the engine which display device we want it to control ----------
  457.     result = AVEngineComponentTargetDevice( *engine, displayID );
  458.     if ( result != noErr )
  459.     {
  460.         StopAlert( kComponentTargetAlertID, NULL );
  461.         return -4;
  462.     }    
  463.             
  464.     return result;    
  465. }
  466.  
  467. //****************************************************************************************
  468. // SetupDialog
  469. //
  470. //    
  471. //----------------------------------------------------------------------------------------
  472. DialogPtr SetupDialog (ComponentInstance engine, OurDMNotifyDataPtr dataP)
  473. {
  474.     OSErr                    result                     = noErr;
  475.     DialogPtr                dp                         = NULL;
  476.     ControlHandle            brightnessSliderCtl;
  477.     ControlHandle            contrastSliderCtl;
  478.     ProcessSerialNumber        currentPSN;
  479.  
  480.     //--- Grab our dialog from resource -------------------------
  481.     dp = GetNewDialog( kDialogID, NULL, (WindowPtr) -1 );
  482.     
  483.     if ( ResError() == noErr && dp != NULL )
  484.     {
  485.         short             itemType;
  486.         Rect            itemRect;
  487.         Handle            itemHdl;
  488.         short            min, max, value;
  489.     
  490.         SetPort( (GrafPtr) dp );
  491.  
  492.         //--- Set up contrast slider ------------------------------
  493.         gContrastSliderUPP = NewControlActionProc( ContrastActionProc );
  494.  
  495.         GetDialogItem( dp, kContrastSliderItem, &itemType, &itemHdl, &itemRect );
  496.         result = ContrastEngineGetContrastRange( engine, &min, &max );
  497.         if ( result == noErr )
  498.         {
  499.             result = ContrastEngineGetContrast( engine, &value);
  500.             if ( result == noErr )
  501.             {                
  502.                 //--- Get and use the system slider procs - this is for 8.0 and later only.
  503.                 contrastSliderCtl = NewControl ( dp, 
  504.                                                  &itemRect, 
  505.                                                  "\p", 
  506.                                                  false, 
  507.                                                  value,
  508.                                                  min, 
  509.                                                  max, 
  510.                                                  kControlSliderProc + kControlSliderLiveFeedback + kControlSliderNonDirectional, 
  511.                                                  0);
  512.         
  513.                 //--- Associate this control with our dialog and set up the control action proc
  514.                 SetDialogItem( dp, kContrastSliderItem, ctrlItem, (Handle) contrastSliderCtl, &itemRect );
  515.                 SetControlReference( contrastSliderCtl, (long) engine );
  516.                 SetControlAction( contrastSliderCtl, gContrastSliderUPP );
  517.                 ShowControl( contrastSliderCtl );
  518.             }
  519.         }
  520.         if ( result != noErr )
  521.         {
  522.             StopAlert( kComponentMiscAlertID, NULL );
  523.             return NULL;
  524.         }
  525.         
  526.         //--- Set up brightness slider ------------------------------
  527.         gBrightnessSliderUPP = NewControlActionProc( BrightnessActionProc );
  528.  
  529.         GetDialogItem( dp, kBrightnessSliderItem, &itemType, &itemHdl, &itemRect );
  530.         result = ContrastEngineGetBrightnessRange( engine, &min, &max );
  531.         if ( result == noErr )
  532.         {
  533.             result = ContrastEngineGetBrightness( engine, &value);
  534.             if ( result == noErr )
  535.             {                
  536.                 //--- Get and use the system slider procs - this is for 8.0 and later only.
  537.                 brightnessSliderCtl = NewControl ( dp, 
  538.                                                    &itemRect, 
  539.                                                    "\p", 
  540.                                                    false, 
  541.                                                    value,
  542.                                                       min, 
  543.                                                       max, 
  544.                                                       kControlSliderProc + kControlSliderLiveFeedback + kControlSliderNonDirectional, 
  545.                                                       0);
  546.         
  547.                 //--- Associate this control with our dialog and set up the control action proc
  548.                 SetDialogItem( dp, kBrightnessSliderItem, ctrlItem, (Handle) brightnessSliderCtl, &itemRect);
  549.                 SetControlReference( brightnessSliderCtl, (long) engine );
  550.                 SetControlAction( brightnessSliderCtl, gBrightnessSliderUPP );
  551.                 ShowControl( brightnessSliderCtl );
  552.             }
  553.         }
  554.         if ( result != noErr )
  555.         {
  556.             StopAlert( kComponentMiscAlertID, NULL );
  557.             return NULL;
  558.         }
  559.         
  560.         //--- Set up some stuff used by the notification function (i.e. when Display Mgr calls us)
  561.         dataP->engine             = engine;
  562.         dataP->dp                 = dp;
  563.         dataP->brightnessCtl     = brightnessSliderCtl;
  564.         dataP->contrastCtl         = contrastSliderCtl;
  565.  
  566.         //----------------------------------------------------------------------
  567.         // Register for notification with the Display Manager so we can update
  568.         // the sliders if brightness or contrast changes outside of our demo app.
  569.         // Display Mgr will call us whenever brightness or contrast change so
  570.         // we can update our sliders to reflect the actual values.
  571.         //----------------------------------------------------------------------
  572.         GetCurrentProcess( ¤tPSN );
  573.         gDMNotifyUPP = NewDMExtendedNotificationProc( BrightnessContrastNotify );
  574.         DMRegisterExtendedNotifyProc( gDMNotifyUPP, (void*) dataP, (unsigned short) NULL, ¤tPSN );
  575.         
  576.         //--- show our dialog box ---------------------------------
  577.         ShowWindow( (WindowPtr) dp );        
  578.     }
  579.     
  580.     return dp;
  581. }
  582.  
  583. //****************************************************************************************
  584. // ResetSettings
  585. //
  586. //    
  587. //----------------------------------------------------------------------------------------
  588. OSErr ResetSettings (ComponentInstance engine, short brightness, short contrast)
  589. {
  590.     OSErr    result = noErr;
  591.     
  592.     //--- Call the engine to reset the values for brightness and contrast.
  593.     //--- We won't redraw the sliders here: Display Mgr will notify us later
  594.     //--- so we can update the sliders later.
  595.     result = ContrastEngineSetBrightness( engine, brightness );
  596.     if ( result == noErr )
  597.         result = ContrastEngineSetContrast( engine, contrast );
  598.         
  599.     if ( result != noErr )
  600.         StopAlert( kComponentMiscAlertID, NULL );
  601.         
  602.     return result;
  603. }
  604.  
  605. //****************************************************************************************
  606. // FindBCEngine
  607. //
  608. //    
  609. //----------------------------------------------------------------------------------------
  610. OSErr FindBCEngine (AVIDType displayID, Component *theEnginePtr)
  611. {
  612.     ComponentResult                result;
  613.     DMListType                    engineList             = NULL;
  614.     DMListIndexType                engineCount         = 0;
  615.     DMComponentListIteratorUPP    theListIteratorUPP;
  616.  
  617.     //--- Pre-init the returned engine ptr ------------------------------
  618.     *theEnginePtr = NULL;
  619.     
  620. #if SUPPORT_OLD_BC_ENGINES
  621.  
  622.     //-------------------------------------------------------------------
  623.     // Currently, there are two types of brightness/contrast engines:
  624.     //
  625.     //   kContrastEngineComponentSubType
  626.     //   kOldContrastEngineComponentSubType
  627.     //
  628.     // The first engine type is more general and can handle all apple
  629.     // displays. The second engine type is meant to be used only with 
  630.     // macs that have built-in displays (like the iMac or the all-in-one
  631.     // PowerMac G3). Currently, the former engine type cannot control
  632.     // brightness/contrast on the built-in monitors.
  633.     //
  634.     // However, the latter is being phased out, and in a little while
  635.     // we will provide a single engine type (i.e. kContrastEngineComponentSubType)
  636.     // that can handle all apple displays -- built-in or otherwise. At that
  637.     // point in time, one would only need to ask for and use one single
  638.     // engine type.
  639.     //
  640.     // In the meantime, we can find an appropriate engine to use with
  641.     // any given GDevice by looking for kOldContrastEngineComponentSubType
  642.     // first. If an engine is returned by DMNewAVEngineList, we'll know
  643.     // that the given GDevice is a built-in display. If no engines are
  644.     // returned, then we know that we need to look for the more general
  645.     // kContrastEngineComponentSubType engine type. 
  646.     //
  647.     // Note that Apple's brightness/contrast engines do not work with
  648.     // third-party displays.
  649.     //-------------------------------------------------------------------
  650.  
  651.     result = DMNewAVEngineList( displayID,                            
  652.                                 kOldContrastEngineComponentSubType,
  653.                                 kMinimumFidelity,                    
  654.                                 0,
  655.                                 0,
  656.                                 &engineCount,
  657.                                 &engineList );
  658. #endif
  659.  
  660.     //-------------------------------------------------------------------
  661.     // DMNewAVEngineList()
  662.     //
  663.     //   DMNewAVEngineList is a Display Manager call that can be used to
  664.     //   find engines that will work with a particular display. For example,
  665.     //   in this demo app we are interested in finding a brightness/contrast
  666.     //   engine that will work with the main GDevice. 
  667.     //
  668.     //   Display Manager will only return engines matching the caller's
  669.     //   requirements. Here are some brief descriptions of each parameter:
  670.     //
  671.     //
  672.     //    DMNewAVEngineList ( DisplayIDType         displayID,
  673.     //                         ResType             engineType,
  674.     //                         DMFidelityType         minimumFidelity,
  675.     //                         unsigned long        engineListFlags,
  676.     //                         unsigned long        reserved,
  677.     //                         DMListIndexType *    engineCount,
  678.     //                         DMListType *        engineList )
  679.     //
  680.     //
  681.     //  displayID - the display ID of the display that we want an engine for.
  682.     //
  683.     //  engineType - the type of engine that we are interested in. For
  684.     //               brightness/contrast engines, use the constant
  685.     //                 "kContrastEngineComponentSubType", which will return
  686.     //                 engines that can talk to Apple's displays. Currently,
  687.     //                 you'll need to specify "kOldContrastEngineComponentSubType"
  688.     //                 if you want an engine to control built-in displays like
  689.     //                 on the iMac or the all-in-one PowerMac G3. In the near
  690.     //                 future, one will be able to specify just one constant
  691.     //                 (kContrastEngineComponentSubType) and get the best 
  692.     //                 brightness/contrast engine that'll work with the given
  693.     //                 display ID without using two constants.
  694.     //
  695.     //  minimumFidelity - an arbitrary number used by engines to tell Display
  696.     //                      Manager how well each engine works with the given
  697.     //                      display. Display Manager will not return any engine
  698.     //                      that has a lower fidelity than specified in this
  699.     //                      parameter. In general, use "kMinimumFidelity".
  700.     //
  701.     //  engineListFlags - set to 0.
  702.     //
  703.     //  reserved - set to 0.
  704.     //
  705.     //  engineCount - returns the number of engines found.
  706.     //
  707.     //  engineList - a list of engines that match the requirements. The first
  708.     //                 engine will be the best one to use. See code below for
  709.     //                 grabbing the first engine.
  710.     //
  711.     //-------------------------------------------------------------------
  712.     
  713.     if ( engineCount <= 0 )
  714.     {    
  715.         //--- We couldn't find any old brightness/contrast engines. So
  716.         //--- we'll just look for and use the normal one.
  717.  
  718.         //--- Clean up the engine list if necessary
  719.         if ( engineList != NULL )
  720.             DMDisposeList( engineList );
  721.         
  722.         //--- Ask DisplayMgr for a list of brightness/contrast engines ------
  723.         //--- NOTE: DM _only_ returns engines for the given displayID -------
  724.         result = DMNewAVEngineList( displayID, 
  725.                                     kContrastEngineComponentSubType,
  726.                                     kMinimumFidelity, 
  727.                                     0, 
  728.                                     0, 
  729.                                     &engineCount, 
  730.                                     &engineList);
  731.     }
  732.  
  733.     //--- Did we get an engine? -----------------------------------------
  734.     if ( result == noErr && engineCount > 0 )
  735.     {
  736.         theListIteratorUPP = NewDMComponentListIteratorProc(BCTargetIterator);
  737.         
  738.         //--- Get the first engine in list ------------------------------
  739.         result = DMGetIndexedComponentFromList( engineList, 0, 0, theListIteratorUPP, theEnginePtr );
  740.  
  741.         //--- Get rid of the list routine descriptor
  742.         DisposeRoutineDescriptor(theListIteratorUPP);
  743.     }
  744.     else
  745.     {
  746.         result = -1;
  747.     }
  748.  
  749.     //--- Dispose of the list --------------------------------------------
  750.     if ( engineList != NULL )
  751.         DMDisposeList( engineList );
  752.  
  753.     return result;
  754. }
  755.  
  756. //****************************************************************************************
  757. // BCTargetIterator
  758. //
  759. //    
  760. //----------------------------------------------------------------------------------------
  761. static pascal void BCTargetIterator (void* userData, DMListIndexType itemIndex, DMComponentListEntryPtr listInfo)
  762. {
  763.     #pragma unused(itemIndex)
  764.     
  765.     *(Component *)userData = listInfo->itemComponent;
  766. }
  767.  
  768. //****************************************************************************************
  769. // BrightnessActionProc
  770. //
  771. //    
  772. //----------------------------------------------------------------------------------------
  773. pascal void BrightnessActionProc (ControlHandle theControl, short partCode)
  774. {
  775. #pragma unused (partCode)
  776.  
  777.     ComponentInstance     engine         = (ComponentInstance) GetControlReference( theControl);
  778.     short                brightness     = GetControlValue( theControl );
  779.     
  780.     //--- Set the brightness. Since we can't pass back errors, just ignore any error
  781.     ContrastEngineSetBrightness( engine, brightness );
  782.     
  783.     return;
  784. }
  785.  
  786. //****************************************************************************************
  787. // ContrastActionProc
  788. //
  789. //    
  790. //----------------------------------------------------------------------------------------
  791. pascal void ContrastActionProc (ControlHandle theControl, short partCode)
  792. {
  793. #pragma unused (partCode)
  794.  
  795.     ComponentInstance     engine         = (ComponentInstance) GetControlReference( theControl);
  796.     short                contrast     = GetControlValue( theControl );
  797.     
  798.     //--- Set the contrast. Since we can't pass back errors, just ignore any error
  799.     ContrastEngineSetContrast( engine, contrast );
  800.     
  801.     return;
  802. }
  803.                                                          
  804. //****************************************************************************************
  805. // BrightnessContrastNotify
  806. //
  807. //  This function is registered with Display Mgr (see SetupDialog) and is called
  808. //  by Display Mgr whenever the contrast or the brightness changes on any display.
  809. //  All we have to do is update our brightness and contrast sliders to
  810. //  reflect this change. This way, if some other app changes the brightness/contrast
  811. //  behind our backs (e.g. Monitors control panel), our sliders will pick up these
  812. //  changes while the demo app is running.
  813. //
  814. //----------------------------------------------------------------------------------------
  815. pascal void BrightnessContrastNotify (void* userData, short theMessage, void* notifyData)
  816. {
  817.     OurDMNotifyDataPtr        dataP = (OurDMNotifyDataPtr) userData;
  818.     DependentNotifyPtr         dependentNotifyData = NULL;
  819.     
  820.     //--- If it's not a dependent notification, we don't care ------------
  821.     if ( theMessage != kDMNotifyDependents )
  822.         return;
  823.     
  824.     //--- We need the notification data for further analysis -------------
  825.     dependentNotifyData = (DependentNotifyPtr)notifyData;
  826.     if ( dependentNotifyData == NULL )
  827.         return;
  828.     
  829.     //--- If it's not the display that we are interested in, we don't care
  830.     if ( dependentNotifyData->notifyPortID != gOurDisplayID )
  831.         return;
  832.  
  833.     //--- If it's not a brightness/contrast change or device reset, we don't care
  834.     if ( dependentNotifyData->notifyType != kContrastChanged && 
  835.          dependentNotifyData->notifyType != kBrightnessChanged &&
  836.          dependentNotifyData->notifyType != kAVNotifyDeviceReset )
  837.     {
  838.         return;
  839.     }
  840.     
  841.     //--- Update the sliders to reflect any changes. We have enough information
  842.     //--- to only update either the brightness or the contrast slider, but
  843.     //--- we'll be lazy and update both.
  844.     UpdateSliders( dataP );
  845.     
  846.     return;
  847. }
  848.